#include <ximera/system/pluginmanager.hpp>
#include <ximera/assert.hpp>
#include <ximera/exception.hpp>

namespace ximera { namespace system
{
    SharedPtr<IPlugin> PluginManager::loadPlugin(String const& libraryFile)
    {
        SharedPtr<Library> library(new Library(libraryFile));
        InitFunctionType* initPlugin = library->loadFunction<InitFunctionType>("ximera_initPlugin");
        
        XIMERA_ASSERT(initPlugin, XIMERA_THROW(InvalidParamException, L"Could not load plugin initialization function"));

        SharedPtr<IPlugin> newPlugin(initPlugin());
        _plugins.insert(std::make_pair(newPlugin->name(), newPlugin));
        _libraries.push_back(library);

        return newPlugin;
    }

    SharedPtr<IPlugin> PluginManager::plugin(String const& name)
    {
        ConstIterator found = _plugins.find(name);
        if (found == _plugins.end())
            return SharedPtr<IPlugin>();

        return found->second;
    }

    PluginManager::ConstIterator PluginManager::begin() const 
    {
        return _plugins.begin();
    }

    PluginManager::ConstIterator PluginManager::end() const 
    {
        return _plugins.end();
    }
}}